#ifndef CHANNEL_ALLOCATION_H
#define CHANNEL_ALLOCATION_H

#include "node-manager.h"
#include "data-collector.h" // 这里包含了ChannelAllocationResult结构体
#include "ns3/object.h"
#include "ns3/nstime.h"
#include "ns3/event-id.h"
#include <map>

namespace ns3 {

class ChannelAllocation : public Object
{
public:
    static TypeId GetTypeId();
    
    ChannelAllocation();  // 默认构造函数
    virtual ~ChannelAllocation();
    
    // 设置信道数量
    void SetNumberOfChannels(uint32_t channels);
    
    // 设置节点管理器
    void SetNodeManager(NodeManager* nodeManager);
    
    // 设置数据收集器
    void SetDataCollector(DataCollector* dataCollector);
    
    // 设置是否允许连接卫星或地面基站
    void SetAllowSatelliteConnection(bool allow);
    void SetAllowGroundStationConnection(bool allow);
    
    // 获取当前分配
    std::map<uint32_t, int> GetCurrentAllocation() const;
    
    // 计算SINR和干扰
    double CalculateSINR(uint32_t nodeId, int channelId);
    double CalculateInterference(uint32_t nodeId, int channelId);
    
    // 添加新的性能计算方法
    double CalculateThroughput(double sinr, NodeType nodeType);
    double CalculateDelay(uint32_t nodeId, int channelId);
    double CalculatePathLoss(uint32_t nodeId, int channelId);
    
    // 添加: 根据距离判断地面站连接是否可行
    bool IsGroundStationConnectionFeasible(double distance, double sinr);
    
    // 添加: 根据仰角判断卫星连接是否可行
    bool IsSatelliteConnectionFeasible(double elevationAngle, double sinr);
    
    // 启动和停止周期性分配
    void StartPeriodic(Time interval);
    void StopPeriodic();
    
    /**
     * 启用实时日志记录
     * @param enable 是否启用
     * @param frequency 日志频率（秒）
     */
    void EnableRealTimeLogging(bool enable, int frequency);
    
    /**
     * 记录并打印当前信道分配情况
     */
    virtual void LogAllocationResults() = 0;
    
protected:
    // 执行分配 - 由派生类实现
    virtual std::map<uint32_t, int> AllocateChannels() = 0;
    
    // 周期性分配
    void PeriodicAllocation();
    
    NodeManager* m_nodeManager;
    DataCollector* m_dataCollector;
    uint32_t m_numChannels;
    bool m_allowSatelliteConnection;
    bool m_allowGroundStationConnection;
    bool m_realTimeLoggingEnabled; // 是否启用实时日志
    int m_loggingFrequency; // 日志频率
    
    std::map<uint32_t, int> m_currentAllocation;
    Time m_allocationInterval;
    EventId m_allocationEvent;
    
    // 执行信道分配并记录结果
    virtual void DoAllocateChannels();
    
    /**
     * \brief 根据节点ID获取车辆节点指针
     * \param nodeId 节点ID
     * \return 车辆节点指针，如果未找到则返回nullptr
     */
    Ptr<Node> GetVehicleNodeById(uint32_t nodeId);
    
    /**
     * \brief 根据信道ID获取信道节点指针
     * \param channelId 信道ID
     * \return 信道节点指针，如果未找到则返回nullptr
     */
    Ptr<Node> GetChannelNodeById(int channelId);
};

} // namespace ns3

#endif /* CHANNEL_ALLOCATION_H */
